#include <iostream>
#include <string>
#include <memory>
#include <cstdlib>
#include <unistd.h>
#include "socket.hpp"
#include "protocol.hpp"

void Usage(std::string proc)
{
    std::cout << "Usage:" << proc << "ip" << ' ' << "port" << std::endl;
}

class Factory
{
public:
    Factory()
        : op("+-*/%&")
    {
        srand(time(nullptr));
    }

    Request buildRequest()
    {
        int x = rand() % 7;
        usleep(10);
        int y = rand() % 5;
        int oper = rand() % op.size();
        return Request(x, y, oper);
    }

private:
    std::string op;
};

int main(int argc, char *argv[])
{
    if (argc != 3)
    {
        Usage(argv[0]);
        return 0;
    }
    std::string ip(argv[1]);
    uint16_t port = std::stoi(argv[2]);
    std::shared_ptr<net::Socket> sp = std::make_shared<net::TcpSocket>();
    InetAddr addr(ip, port);
    Factory factory;
    sp->CreateSocketOrDie();
    bool ret = sp->Connetcor(addr);
    while (ret)
    {
        sleep(1);
        Request req = factory.buildRequest();
        std::string send_str;
        req.serialize(&send_str); // 对请求进行序列化
        std::cout << "serialize:" << send_str << std::endl;

        send_str = EnCode(send_str); // 添加报头
        std::cout << "EnCode:" << send_str << std::endl;

        // 发消息
        sp->Send(send_str);
        // 收消息
        std::string receive_str;
        int n = sp->Recv(&receive_str);
        if (n <= 0)
        {
            break;
        }
        std::string package = DeCode(receive_str);
        if (package.empty())
        {
            continue;
        }
        Result result;
        // 反序列化
        result.deserialization(package);
        std::cout << "result:" << result.get_result() << ' ' << result.get_code() << std::endl;
    }
    return 0;
}